package com.bat.conf;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @Author: zpf
 * @Date: 2019/11/23 下午6:05
 */
@Configuration
@Slf4j
public class HttpPool {
    @Bean("feignHttpClient")
    public HttpClient httpClient() {
        log.info("init feign httpclient configuration ");
        // 生成默认请求配置
        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
        // 超时时间
        requestConfigBuilder.setSocketTimeout(30 * 1000);
        // 连接时间
        requestConfigBuilder.setConnectTimeout(30 * 1000);
        RequestConfig defaultRequestConfig = requestConfigBuilder.build();
        // 连接池配置
        // 长连接保持30秒
        final PoolingHttpClientConnectionManager pollingConnectionManager =
            new PoolingHttpClientConnectionManager(60, TimeUnit.MILLISECONDS);
        // 总连接数
        pollingConnectionManager.setMaxTotal(5000);
        // 同路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(100);

        // httpclient 配置
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
        HttpClient client = httpClientBuilder.build();

        // 启动定时器，定时回收过期的连接
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "feign_httclient_pool_" + r.hashCode());
            }
        });
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            log.debug("=====closeIdleConnections===");
            pollingConnectionManager.closeExpiredConnections();
            pollingConnectionManager.closeIdleConnections(5, TimeUnit.SECONDS);
        }, 10 * 1000, 10 * 10000, TimeUnit.SECONDS);
        log.info("===== Apache httpclient 初始化连接池===");

        return client;
    }

}
